package com.tanhua.dubbo.api;

import com.mongodb.internal.connection.QueryResult;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@DubboService
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 通过动态id，分页查询评论列表
     *
     * @param page
     * @param pageSize
     * @param movementId
     * @return
     */
    @Override
    public PageResult findPage(Long page, Long pageSize, String movementId) {
        //1. 构建查询条件
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(movementId))
                // 多条件使用.and()
                .and("commentType").is(CommentType.COMMENT.getType()));
        //2. 统计总数
        long total = mongoTemplate.count(query, Comment.class);
        //3. 总数>start
        List<Comment> commentList = new ArrayList<>();
        long start = (page-1) * pageSize;
        // 保证这一页page， 有数据可查。e.g: total=20, 当page=1, pagesize=10. start=0. page=2, start=10; page=3, start=20 total>start?
        if(total > start) {
            //4. 设置分页参数
            query.skip(start).limit(pageSize.intValue());
            //5. 按时间降序
            query.with(Sort.by(Sort.Order.desc("created")));
            //6. 分页查询
            commentList = mongoTemplate.find(query, Comment.class);
        }
        //7. 构建pageResult返回
        return new PageResult(page,pageSize,total,commentList);
    }

    /**
     * 发表评论
     *
     * @param pojo
     */
    @Override
    public Integer add(Comment pojo) {
        //1. 通过动态id查询作者id
        Movement movement = mongoTemplate.findById(pojo.getPublishId(), Movement.class);
        //2. 设置回pojo
        pojo.setPublishUserId(movement.getUserId());
        //3. 设置创建时间
        pojo.setCreated(System.currentTimeMillis());
        //4. 添加记录
        mongoTemplate.insert(pojo);

        //5. 更新【自增】动态的评论数
        // 查询用query
        Query query = new Query(Criteria.where("_id").is(pojo.getPublishId()));
        // 更新用update
        Update update = new Update();
        //根据不同的评论类型，返回要更新数量的字段名
        String colName = getCollName(pojo.getCommentType());
        // 数量自增1
        update.inc(colName,1);

        // 查找并且修改
        FindAndModifyOptions fmo = new FindAndModifyOptions();
        fmo.returnNew(true); // 执行完后，返回最新的值
        //查找并且修改
        movement = mongoTemplate.findAndModify(query, update, fmo, Movement.class);
        // 返回最新的数量
        return movement.staticsCount(pojo.getCommentType());
    }

    /**
     * 取消点赞
     *
     * @param pojo
     * @return
     */
    @Override
    public Integer remove(Comment pojo) {
        //1. 删除评论表记录
        Query query = new Query(Criteria.where("publishId").is(pojo.getPublishId())
                .and("commentType").is(pojo.getCommentType())
                .and("userId").is(pojo.getUserId())
        );
        mongoTemplate.remove(query, Comment.class);
        //2. 更新动态表中的点赞数，
        // 查询用query
        Query movementQuery = new Query(Criteria.where("_id").is(pojo.getPublishId()));
        // 更新用update
        Update update = new Update();
        //根据不同的评论类型，返回要更新数量的字段名
        String colName = getCollName(pojo.getCommentType());
        // 数量自减1
        update.inc(colName,-1);

        // 查找并且修改
        FindAndModifyOptions fmo = new FindAndModifyOptions();
        fmo.returnNew(true); // 执行完后，返回最新的值
        //查找并且修改
        Movement movement = mongoTemplate.findAndModify(movementQuery, update, fmo, Movement.class);
        //3. 返回最新数量
        return movement.staticsCount(pojo.getCommentType());
    }

    /**
     * 根据不同的评论类型，返回要更新数量的字段名
     * @param commentType
     * @return
     */
    private String getCollName(int commentType) {
        if(CommentType.LIKE.getType() == commentType){
            return "likeCount";
        }else if(CommentType.COMMENT.getType() == commentType){
            return "commentCount";
        }else{
            return "loveCount";
        }
    }


}
